/*
 * Copyright 2007 Brian Watkins
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package bw.util;

public abstract class Agent implements Runnable
{
    private String _name = null;
    private Thread _me = null;
    private boolean _running = false;
    private long _sleepTime = 60000L;

    //Agent does something on its own. It wakes
    //up periodically and performs some task.
    //Subclasses implement performAction().
    //A sleeptime of 0 means no sleep between calls to performAction() 
    //and in that case the subclass should handle blocking or sleeping on its own.

    public Agent ( String name, long sleepTime )
    {
        _name = name;
        _sleepTime = sleepTime;
    }

    protected void setSleepTime ( long sleepTime )
    {
        _sleepTime = sleepTime;
    }

    public void start ()
    {
        if ( !_running )
        {
            _me = new Thread( this );
            _running = true;
            _me.start();
        }
    }

    public void run ()
    {
        Log.getInstance().write( "Started Agent: " + _name );

        while ( _running )
        {
            performAction();

            if ( _sleepTime > 0L )
            {
                try
                {
                    Thread.sleep( _sleepTime );
                }
                catch ( InterruptedException ex )
                {
                    //nothing
                }
            }
        }

        Log.getInstance().write( "Stopped Agent: " + _name );
    }

    public abstract void performAction();

    public void shutdown ()
    {
        if ( _running )
        {
            _running = false;
            _me.interrupt();

            try
            {
                _me.join( 5000L );
            }
            catch ( InterruptedException ex )
            {
                //nothing
            }
        }
    }
}